home *** CD-ROM | disk | FTP | other *** search
-
- /*
- ** This source code was written by Tim Endres
- ** Email: time@ice.com.
- ** USMail: 8840 Main Street, Whitmore Lake, MI 48189
- **
- ** Some portions of this application utilize sources
- ** that are copyrighted by ICE Engineering, Inc., and
- ** ICE Engineering retains all rights to those sources.
- **
- ** Neither ICE Engineering, Inc., nor Tim Endres,
- ** warrants this source code for any reason, and neither
- ** party assumes any responsbility for the use of these
- ** sources, libraries, or applications. The user of these
- ** sources and binaries assumes all responsbilities for
- ** any resulting consequences.
- */
-
-
- #pragma segment TCLCBTREE
-
- #include "tickle.h"
- #include "tcl.h"
-
- #include "cdefs.h"
- #include "db.h"
- #include "btree.h"
-
- extern int errno;
- extern int macintoshErr;
-
-
- typedef struct {
- DB *db;
- char name[32];
- } CBTREE_NAMED_DB;
-
- #define MAX_DBS 8
-
- static int _max_dbs_ = 0;
- static CBTREE_NAMED_DB *_dbs_ = NULL;
-
- init_tcl_cbtree()
- {
- int i;
-
- _dbs_ = (CBTREE_NAMED_DB *) malloc(sizeof(CBTREE_NAMED_DB) * MAX_DBS);
- if (_dbs_ == NULL)
- _max_dbs_ = 0;
- else
- _max_dbs_ = MAX_DBS;
-
- for (i=0; i<_max_dbs_; ++i)
- {
- _dbs_[i].db = (DB *)0;
- _dbs_[i].name[0] = '\0';
- }
- }
-
- close_tcl_cbtree()
- {
- int i;
-
- for (i=0; i<_max_dbs_; ++i)
- {
- if (_dbs_[i].db != (DB *)0)
- (* _dbs_[i].db->close)(_dbs_[i].db);
- }
- }
-
- int
- tcl_btree_cmp(p1, p2)
- char *p1, *p2;
- {
- /*fprintf(stderr, "my_btree_cmp: p1 x%lx '%s' p2 x%lx '%s'\n", p1, p1, p2, p2);*/
- return strcmp(p1, p2);
- }
-
- int
- Cmd_CBTOpen(clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- short wdRefNum;
- int index, push_err, myerr;
- #pragma unused (clientData)
-
- if (argc != 3)
- {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " dbName dbFileName\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- for (index = 0 ; index < _max_dbs_ ; ++index)
- {
- if (_dbs_[index].db == NULL)
- break;
-
- if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" duplicate DB name '",
- argv[1], "'", (char *) NULL);
- return TCL_ERROR;
- }
- }
-
- if (index >= _max_dbs_)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" max DB's open", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- BTREEINFO openinfo;
-
- myerr = TclMac_CWDCreateWD(&wdRefNum);
- if (myerr != noErr)
- {
- Tcl_AppendResult(interp, "could not create working directory - ",
- Tcl_MacGetError(interp, myerr), NULL);
- return TCL_ERROR;
- }
-
- push_err = TclMac_CWDPushVol();
-
- openinfo.flags = R_DUP;
- openinfo.cachesize = 0;
- openinfo.compare = tcl_btree_cmp; /* use strcmp() */
- openinfo.lorder = BIG_ENDIAN;
- openinfo.psize = 4096;
-
- SetVol(NULL, wdRefNum);
- _dbs_[index].db = btree_open(argv[2], O_RDWR | O_CREAT, 0666, &openinfo);
-
- if (push_err == noErr)
- TclMac_CWDPopVol();
-
- TclMac_CWDDisposeWD(wdRefNum);
-
- if (_dbs_[index].db == (DB *)0)
- {
- strcpy(_dbs_[index].name, "--CLOSED--");
- Tcl_AppendResult(interp, "\"", argv[0], "\" error opening DB", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- strcpy(_dbs_[index].name, argv[1]);
- return TCL_OK;
- }
- }
- }
-
- int
- Cmd_CBTInsert(clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int index, result;
- DBT key,
- data;
- #pragma unused (clientData)
-
- if (argc != 4 && argc != 5)
- {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " dbName key data ?replace?\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- for (index = 0 ; index < _max_dbs_ ; ++index)
- {
- if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
- break;
- }
-
- if (index >= _max_dbs_)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
- argv[1], "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- key.data = argv[2];
- key.size = strlen(argv[2]) + 1;
- data.data = argv[3];
- data.size = strlen(argv[3]) + 1;
-
- result = (* _dbs_[index].db->put) ( _dbs_[index].db, &key, &data,
- (argc == 4 ? R_PUT : R_NOOVERWRITE) );
- if (result < 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" error storing data", (char *) NULL);
- return TCL_ERROR;
- }
- else if (result > 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" key already exists", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- return TCL_OK;
- }
- }
- }
-
- int
- Cmd_CBTGetKey(clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int index, result;
- DBT key,
- data;
- #pragma unused (clientData)
-
- if (argc != 3 && argc != 4)
- {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " dbName key ?varName?\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- for (index = 0 ; index < _max_dbs_ ; ++index)
- {
- if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
- break;
- }
-
- if (index >= _max_dbs_)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
- argv[1], "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- key.data = argv[2];
- key.size = strlen(argv[2]) + 1;
-
- result = (* _dbs_[index].db->get) ( _dbs_[index].db, &key, &data, 0 );
-
- if (result < 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
- "\" DB error", (char *) NULL);
- return TCL_ERROR;
- }
- if (result > 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
- "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- if (argc == 4)
- Tcl_SetVar(interp, argv[3], data.data, 0);
- else
- Tcl_AppendResult(interp, data.data, (char *) NULL);
-
- return TCL_OK;
- }
- }
- }
-
- int
- Cmd_CBTDelete(clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int index, result;
- DBT key;
- #pragma unused (clientData)
-
- if (argc != 3)
- {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " dbName key\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- for (index = 0 ; index < _max_dbs_ ; ++index)
- {
- if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
- break;
- }
-
- if (index >= _max_dbs_)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
- argv[1], "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- key.data = argv[2];
- key.size = strlen(argv[2]) + 1;
-
- result = (* _dbs_[index].db->del) ( _dbs_[index].db, &key, 0);
-
- if (result < 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
- "\" DB error", (char *) NULL);
- return TCL_ERROR;
- }
- if (result > 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" key \"", argv[2],
- "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- return TCL_OK;
- }
- }
- }
-
- int
- Cmd_CBTSeq(clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int index, result;
- DBT key, data;
- char *dvarname;
- char *kvarname;
- unsigned long flags;
- #pragma unused (clientData)
-
- if (argc < 3 || argc > 6)
- {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " dbName FIRST|LAST|NEXT|PREV|[SEEK key] ?kVarName? ?dVarName?\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- for (index = 0 ; index < _max_dbs_ ; ++index)
- {
- if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
- break;
- }
-
- if (index >= _max_dbs_)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
- argv[1], "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- dvarname = NULL;
- kvarname = NULL;
- key.data = "";
- key.size = 0;
- if (strcmp(argv[2], "FIRST") == 0)
- {
- if (argc >= 4)
- kvarname = argv[3];
- if (argc >= 5)
- dvarname = argv[4];
- flags = R_FIRST;
- }
- else if (strcmp(argv[2], "LAST") == 0)
- {
- if (argc >= 4)
- kvarname = argv[3];
- if (argc >= 5)
- dvarname = argv[4];
- flags = R_LAST;
- }
- else if (strcmp(argv[2], "NEXT") == 0)
- {
- if (argc >= 4)
- kvarname = argv[3];
- if (argc >= 5)
- dvarname = argv[4];
- flags = R_NEXT;
- }
- else if (strcmp(argv[2], "PREV") == 0)
- {
- if (argc >= 4)
- kvarname = argv[3];
- if (argc >= 5)
- dvarname = argv[4];
- flags = R_PREV;
- }
- else if (strcmp(argv[2], "SEEK") == 0)
- {
- key.data = argv[3];
- key.size = strlen(argv[3]) + 1;
-
- if (argc >= 5)
- kvarname = argv[4];
-
- if (argc >= 6)
- dvarname = argv[5];
-
- flags = R_CURSOR;
- }
-
- result = (* _dbs_[index].db->seq) (_dbs_[index].db, &key, &data, flags);
- if (result < 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" DB error", (char *) NULL);
- return TCL_ERROR;
- }
- else if (result > 0)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" no more keys", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- if (kvarname != NULL)
- Tcl_SetVar(interp, kvarname, key.data, 0);
- else
- Tcl_AppendResult(interp, "{", key.data, "}", (char *) NULL);
-
- if (dvarname != NULL)
- Tcl_SetVar(interp, dvarname, data.data, 0);
- else
- Tcl_AppendResult(interp, (kvarname != NULL ? "{" : " {"),
- data.data, "}", (char *) NULL);
-
- return TCL_OK;
- }
- }
- }
-
- int
- Cmd_CBTClose(clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int index, result;
- #pragma unused (clientData)
-
- if (argc != 2)
- {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " dbName\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- for (index = 0 ; index < _max_dbs_ ; ++index)
- {
- if (strcmp(_dbs_[index].name, argv[1]) == SAMESTR)
- break;
- }
-
- if (index >= _max_dbs_)
- {
- Tcl_AppendResult(interp, "\"", argv[0], "\" DB \"",
- argv[1], "\" not found", (char *) NULL);
- return TCL_ERROR;
- }
- else
- {
- result = (* _dbs_[index].db->close) (_dbs_[index].db);
- free(_dbs_[index].db);
- _dbs_[index].db = (DB *)0;
- strcpy(_dbs_[index].name, "--CLOSED--");
- return TCL_OK;
- }
- }
-
- Tcl_InitCBTREE(interp)
- Tcl_Interp *interp;
- {
- Tcl_CreateCommand(interp, "cbt_open", Cmd_CBTOpen,
- (ClientData)NULL, (void (*)())NULL);
- Tcl_CreateCommand(interp, "cbt_close", Cmd_CBTClose,
- (ClientData)NULL, (void (*)())NULL);
- Tcl_CreateCommand(interp, "cbt_insert", Cmd_CBTInsert,
- (ClientData)NULL, (void (*)())NULL);
- Tcl_CreateCommand(interp, "cbt_getkey", Cmd_CBTGetKey,
- (ClientData)NULL, (void (*)())NULL);
- Tcl_CreateCommand(interp, "cbt_delete", Cmd_CBTDelete,
- (ClientData)NULL, (void (*)())NULL);
- Tcl_CreateCommand(interp, "cbt_seq", Cmd_CBTSeq,
- (ClientData)NULL, (void (*)())NULL);
- }
-